using Microsoft.Xna.Framework;
using System.Runtime.Serialization;
using INdT.Sparta.Graphics.Transitions;
using INdT.Sparta.Graphics.Animations;
using System;
using INdT.Sparta.Physics;

namespace INdT.Sparta
{
    [DataContract]
    public abstract class SpartaState : SpartaGroup
    {
        public enum SpartaStateMode
        {
            Deactivated, 
            TransitionOff, 
            TransitionIn, 
            Activated, 
            Loading
        }

        private SpartaStateMode mode;
        [DataMember]
        public SpartaStateMode Mode
        {
            get { return mode; }
            set
            {
                if (mode != value)
                {
                    SpartaStateMode oldMode = mode;
                    mode = value;
                    OnModeChanged(oldMode, mode);
                }
            }
        }

        internal SpartaTransition TransitionIn = SpartaTransition.Default;
        internal SpartaTransition TransitionOut = SpartaTransition.Default;

        internal SpartaAnimationGroup TransitionAnimations;
        
        protected virtual void OnModeChanged(SpartaStateMode oldMode, SpartaStateMode newMode)
        {
            if (newMode == SpartaStateMode.Loading)
            {
                SpartaTransitionAnimation.HandleTransition(this, AnimationGroupEnd, TransitionIn);
            }
            else if (newMode == SpartaStateMode.TransitionOff)
            {
                SpartaTransitionAnimation.HandleTransition(this, AnimationGroupEnd, TransitionOut);
            }
        }

        private void AnimationGroupEnd()
        {
            if (Mode == SpartaStateMode.Loading && TransitionIn.transitionType ==  SpartaTransitionType.None)
            {
                Initialize();
                LoadContent();
                Mode = SpartaStateMode.Activated;
            }
            else if (Mode == SpartaStateMode.TransitionIn)
            {
                Mode = SpartaStateMode.Activated;
            }
            else if (Mode == SpartaStateMode.TransitionOff)
            {
                Mode = SpartaStateMode.Deactivated;
            }
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            if (Mode == SpartaStateMode.TransitionIn)
            {
                if (TransitionIn.transitionType != SpartaTransitionType.None)
                {
                    TransitionAnimations.Update(gameTime);
                }
            }
            else if (Mode == SpartaStateMode.TransitionOff)
            {
                if (TransitionOut.transitionType != SpartaTransitionType.None)
                {
                    TransitionAnimations.Update(gameTime);
                }
            }
            else
            {
                SpartaPhysics.world.Step(Math.Min((float)gameTime.ElapsedGameTime.TotalSeconds, (1f / 30f)));
            }
        }

        public virtual void OnBackButtonPressed()
        {
        }

        public virtual void PrepareForTombstone()
        {
        }

        public override void Dispose()
        {
            if (IsDisposed)
            {
                return;
            }
            if (TransitionAnimations != null)
            {
                TransitionAnimations.Dispose();
            }
            base.Dispose();
        }
    }
}
